<!-- 通用上传文档组件 -->
<template>
  <div class="file-upload-wrap">
    <px-upload
      v-if="props.fileType === 'add' || props.fileType === 'edit'"
      :file-list="fileLists"
      :show-file-list="false"
      multiple
      :limit="props.countLimit"
      :accept="props.fileAccept"
      :action="actionUrl"
      :headers="headers"
      :data="props.fileData"
      :before-upload="beforeUpload"
      :on-progress="upLoadProgress"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :on-exceed="uploadExceed"
    >
      <px-button type="primary" plain :disabled="!uploadDisabled">上传文档</px-button>
      <template #tip>
        <div class="px-upload__tip">
          <span v-if="props.fileTypeValue != ''">⽀持{{ props.fileTypeValue }}格式，</span>⽂档⼤⼩不超过{{ props.fileSize }}M<span
            v-if="props.countLimit !== 999"
            >，文档数量不超过{{ props.countLimit }}个</span
          >
        </div>
      </template>
    </px-upload>
    <px-table :data="fileLists" class="file-table" size="small" max-height="320" border>
      <px-table-column fixed="left" prop="originalName" label="文档名称" min-width="200" show-overflow-tooltip />
      <px-table-column prop="accountName" label="上传人员" min-width="200" show-overflow-tooltip />
      <px-table-column prop="fileSize" label="文档大小" min-width="200" show-overflow-tooltip>
        <template #default="scope">
          {{ convertFileSize(scope.row.fileSize) }}
        </template>
      </px-table-column>
      <px-table-column prop="updateTime" label="上传时间" min-width="200" show-overflow-tooltip>
        <template #default="scope">
          <div v-if="scope.row?.progressShow"><px-progress :percentage="Math.floor(scope.row?.progressPercent)" /></div>
          <div v-else>{{ scope.row.updateTime }}</div>
        </template>
      </px-table-column>
      <px-table-column fixed="right" label="操作" min-width="60" align="center">
        <template #default="scope">
          <px-button
            v-if="props.fileType === 'add' || props.fileType === 'edit'"
            link
            type="primary"
            :disabled="!scope.row?.id"
            @click="fileDelete(scope.row)"
          >
            <px-icon><Delete /></px-icon>
          </px-button>
          <px-button v-if="props.fileType === 'view'" link type="primary" @click="fileDownload(scope.row)">
            <px-icon><Bottom /></px-icon>
          </px-button>
        </template>
      </px-table-column>
    </px-table>
  </div>
</template>

<script setup lang="ts">
import { deleteFile } from "@/api/common";
import { getToken } from "@/utils/auth";
import { PxMessage } from "px-ui";
import { computed, getCurrentInstance, reactive, toRefs, watch } from "vue";

// 调用父级-改变文档列表方法，查看时不调用
const emits = defineEmits(["changeFileList", "saveFileStatus"]);
// 父级传过来的值
const props = defineProps({
  // 文档上传类型add：新增，edit：编辑，view：查看
  fileType: {
    type: String,
    default: "add",
    required: true
  },
  // 文档上传接口url
  actionUrl: {
    type: String,
    default: "/ifp/sharing/api/v1/file/upload",
    required: false
  },
  // 文档上传接口数据
  fileData: {
    type: Object,
    default: () => {},
    required: true
  },
  // 文件上传个数
  countLimit: {
    type: Number,
    default: 999,
    required: false
  },
  // 文档接收类型
  fileAccept: {
    type: String,
    default: "",
    required: false
  },
  // 文档类型提示
  fileTypeValue: {
    type: String,
    default: "",
    required: false
  },
  // 文档大小
  fileSize: {
    type: Number,
    default: 100,
    required: false
  },
  // 文档上传类型为edit/view时，已上传的文档列表
  fileList: {
    type: Array,
    default: () => [],
    required: true
  }
});

// 页面本身的值
const { proxy }: any = getCurrentInstance();
const state = reactive<any>({
  headers: {
    Authorization: "Bearer " + getToken().accessToken || "",
    facCode: localStorage.getItem("facCode") || ""
  },
  fileLists: [], // 文档列表
  fileNumber: 0 // 文档上传数量
});
const { headers, fileLists, fileNumber } = toRefs(state);

// 监视文档上传类型
watch(
  () => [props.fileType, props.fileList],
  val => {
    fileLists.value = val[1];
    fileNumber.value = fileLists.value?.length || 0;
  },
  { immediate: true }
);

// 计算文档是否全部上传完成
const uploadDisabled = computed(() => {
  return fileLists.value.every(item => {
    return (fileLists.value && fileLists.value.length === 0) || item?.id;
  });
});

// 文档大小换算M/K
const convertFileSize = fileSize => {
  if (fileSize === "-") {
    return "-";
  }
  const fileSizeValue = Number(fileSize);
  if (fileSizeValue >= 1024) {
    return Math.round((fileSizeValue / 1024) * 100) / 100 + "M";
  } else {
    return fileSizeValue + "K";
  }
};
// 上传文档之前判断大小及格式
const beforeUpload = rawFile => {
  // 判断文档大小
  if (rawFile.size / 1024 / 1024 > Number(props.fileSize)) {
    PxMessage.error(`上传文档大小不能超过${Number(props.fileSize)}M`);
    return false;
  }
  // 如果有文档格式就判断
  if (props.fileAccept) {
    const acceptList = props.fileAccept;
    let fileType = rawFile.name.split(".").pop().toLowerCase();
    if (acceptList.indexOf(fileType) === -1) {
      PxMessage.error(`只能上传 ${props.fileAccept} 格式的文档`);
      return false;
    }
  }
  return true;
};
// 上传文档过程中获取进度信息
const upLoadProgress = (event, uploadFile) => {
  emits("saveFileStatus", true);
  const idx = fileLists.value.findIndex(item => item?.originalName === uploadFile.name && item.fileSize === "-");
  if (idx !== -1) {
    fileLists.value[idx].progressPercent = Math.floor(event.percent);
  } else {
    fileLists.value.unshift({
      originalName: uploadFile.name,
      accountName: "-",
      fileSize: "-",
      progressShow: true,
      progressPercent: event.percent
    });
  }
};
// 上传成功状态
const uploadSuccess = (response, uploadFile, uploadFiles) => {
  fileNumber.value++;
  // 上传成功通知页面可以保存
  if (fileNumber.value === uploadFiles.length) {
    emits("saveFileStatus", false);
  }
  if (response.success) {
    // 上传成功，通过success为true判断
    const idx = fileLists.value.findIndex(item => item?.originalName === response?.data?.originalName && item?.progressPercent === 100);
    if (idx !== -1) {
      fileLists.value[idx] = response?.data;
      fileLists.value[idx].progressShow = false;
      fileLists.value[idx].progressPercent = 0;
      emits("changeFileList", fileLists.value);
    }
  } else {
    // 后台返回上传失败信息
    PxMessage.error(response.msg);
  }
};
// 上传失败状态error
const uploadError = error => {
  // 此处由于后端未处理，前端先统一写"文档上传失败，请重试"
  PxMessage.error("文档上传失败，请重试");
};
// 上传个数超出限制
const uploadExceed = () => {
  PxMessage.error(`上传文档数量不能超过${props.countLimit}个`);
};
// 文档下载
const fileDownload = (row: any) => {
  const params = {
    id: row.id,
    fileName: row.fileName,
    moduleName: props.fileData?.moduleName
  };
  proxy.download("post", "/sharing/api/v1/file/download", params, row.originalName);
};
// 文档删除
const fileDelete = async (row: any) => {
  const params = {
    fileId: [row.id]
  };
  await deleteFile(params);
  PxMessage.success("文档删除成功");
  fileLists.value = fileLists.value.filter((item: any) => item.id !== row.id);
  emits("changeFileList", fileLists.value);
};
</script>

<style lang="scss" scoped>
.file-upload-wrap {
  width: 100%;

  .px-upload__tip {
    margin-bottom: 18px;
    font-size: 12px;
    color: rgb(0 0 0 / 60%);
  }

  .file-table {
    --px-table-border-color: #dfdfdf;

    :deep(.px-table__header) {
      thead {
        tr {
          background-color: #e7eefb !important;

          th {
            font-size: 13px;
            font-weight: bold;
            color: #000;
            background-color: #e7eefb !important;
          }
        }
      }
    }
  }
}
</style>
